package org.gdgbologna.devfest;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;

import org.gdgbologna.animation.ShowUnshowAnimation;
import org.gdgbologna.resources.Devfest;
import org.gdgbologna.resources.Session;
import org.gdgbologna.resources.Talk;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources.NotFoundException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerTitleStrip;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.androidquery.AQuery;

@TargetApi(11)
@SuppressLint("NewApi")
public class MainActivity extends FragmentActivity implements OnNavigationListener {

	LoadJsonTask ljt;
	ApplicationDevFest app;
	
	ActionBar actionBar;
	
	int fragment_selected;
	PagerTitleStrip titleStrip;

	SectionsPagerAdapter mSectionsPagerAdapter;
	ArrayList<Fragment> fragments;

	ViewPager mViewPager;
	static String[] festString;

	NfcAdapter mNfcAdapter;
	NdefMessage mNdefPushMessage;

	LinearLayout popup_nfc;
	SharedPreferences prefs;
	
	ArrayList <Devfest> devfest = null;
	

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.activity_main);
		
		app = (ApplicationDevFest) this.getApplication();
		prefs = PreferenceManager.getDefaultSharedPreferences(this);

		AQuery aq = new AQuery(this);   
		aq.hardwareAccelerated11();

		devfest = new ArrayList<Devfest>();
		
		fragments = new ArrayList<Fragment>();
		
		/*Fragment allfragment = new AllListFragment();
		fragments.add(allfragment);
		
		Fragment sponsor = new SponsorListFragment();
		fragments.add(sponsor);*/
		
		// Create the adapter that will return a fragment for each of the three primary sections
		// of the app.
		mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
		titleStrip = (PagerTitleStrip) findViewById(R.id.pager_title_strip);

		// Set up the ViewPager with the sections adapter.
		mViewPager = (ViewPager) findViewById(R.id.pager);
		mViewPager.setAdapter(mSectionsPagerAdapter);
		//mViewPager.setCurrentItem(1);

		actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
		actionBar.setDisplayShowTitleEnabled(false);

		festString = getResources().getStringArray(R.array.fest);

		actionBar.setListNavigationCallbacks(
				// Specify a SpinnerAdapter to populate the dropdown list.
				new ArrayAdapter(
						actionBar.getThemedContext(),
						android.R.layout.simple_list_item_1,
						android.R.id.text1,
						festString),
						this);

		mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
		if (mNfcAdapter != null) {
			// if device support NFC
			String url = "https://play.google.com/store/apps/details?id=org.gdgbologna.devfest2012"; 
			byte[] payload = url.getBytes(); 
			//NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, payload, new byte[0], payload);
			NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, payload, new byte[0], payload);
			mNdefPushMessage = new NdefMessage(new NdefRecord[]  { ndefRecord }); 

			popup_nfc = (LinearLayout) findViewById(R.id.popup_nfc);
			Button left = (Button)popup_nfc.findViewById(R.id.btn_left_nfc);
			left.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					closePopupNfc();
				}
			});

			Button right = (Button)popup_nfc.findViewById(R.id.btn_right_nfc);
			right.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					Editor e = prefs.edit();
					e.putBoolean("show", false);
					e.commit();
					closePopupNfc();
				}
			});
		}
		
		loadJson();
	}

	public void closePopupNfc(){
		ShowUnshowAnimation anim = new ShowUnshowAnimation(popup_nfc, 0, false);
		anim.setDuration(1000);
		popup_nfc.startAnimation(anim);
	}

	public void loadJson(){
		setProgressBarIndeterminateVisibility(true);
		ljt = new LoadJsonTask(this);
		try {
			ljt.execute();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Log.e("error:",e.getLocalizedMessage()+"");
		}
	}

	@Override
	public void onResume(){
		super.onResume();

		if (mNfcAdapter != null) {
			mNfcAdapter.setNdefPushMessage(mNdefPushMessage, this);

			if (prefs.getBoolean("show", true)){
				ShowUnshowAnimation anim = new ShowUnshowAnimation(popup_nfc, app.dpiToPixel(100), true);
				anim.setDuration(1000);
				popup_nfc.startAnimation(anim);
			}
		}

		app.tracker.trackPageView("/devfest/"+fragment_selected);

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
	    outState.putInt("navigation_selected", actionBar.getSelectedNavigationIndex());
	    super.onSaveInstanceState(outState);
	}
	
	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
	    super.onRestoreInstanceState(savedInstanceState);
	    int navigation_selected = savedInstanceState.getInt("navigation_selected");
	    //actionBar.setSelectedNavigationItem(navigation_selected);
	}


	public void loadDevfest(int index){
		fragment_selected = index;
		
		/*AllListFragment all = (AllListFragment) fragments.get(0);
		all.changeList(index);*/
		
		
		if (fragments.size()>0){
			AllListFragment all = (AllListFragment) fragments.get(0);
			all.changeList(devfest.get(fragment_selected));
			
			SponsorListFragment sponsor = (SponsorListFragment) fragments.get(1);
			sponsor.changeDevfest(festString[fragment_selected].toLowerCase());
		}else{
			AllListFragment all = AllListFragment.newInstance(devfest.get(fragment_selected));
			fragments.add(all);
			
			SponsorListFragment sponsor = SponsorListFragment.newInstance(festString[fragment_selected].toLowerCase());
			fragments.add(sponsor);
		}
		
		//SponsorListFragment sponsor = (SponsorListFragment) fragments.get(1);
		//sponsor.loadDevfest(festString[fragment_selected].toLowerCase());
		
		/*if (fragments.size()>0) {
			FragmentManager fm = getSupportFragmentManager();
			fm.beginTransaction().remove(fragments.get(0)).commit();
		}
		
		SponsorListFragment sponsor = new SponsorListFragment();
		Bundle args = new Bundle();
		args.putString("fest", festString[fragment_selected].toLowerCase());
		sponsor.setArguments(args);
		fragments.add(sponsor);*/
		
		
		
		
		mSectionsPagerAdapter.notifyDataSetChanged();
		titleStrip.setTextSpacing(titleStrip.getTextSpacing());
	}

	public void endLoadingJson(boolean error,String result) {
		// TODO Auto-generated method stub
		//Log.e("ending load json:","total:"+app.devfest.size());
		if (error){
			Log.e("error:",result);
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
		}else{
			setProgressBarIndeterminateVisibility(false);
			loadDevfest(0);
		}
	}

	static class LoadJsonTask extends AsyncTask<String,Void,String>{
		boolean error = false;
		MainActivity act = null;

		LoadJsonTask(MainActivity activity){
			attach(activity);
		}

		@Override
		protected String doInBackground(String...params) {
			// TODO Auto-generated method stub

			String res = null;
			for (String fest : festString){
				fest = fest.toLowerCase();

				try {
					@SuppressWarnings("rawtypes")
					Class jsonRaw = R.raw.class;
					Field field = jsonRaw.getField(fest);
					Devfest devfestToAdd = new Devfest(fest);

					InputStream is = act.getResources().openRawResource(field.getInt(null));
					Writer writer = new StringWriter();
					char[] buffer = new char[1024];
					try {
						// Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
						Reader reader = new BufferedReader(new InputStreamReader(is));
						int n;
						while ((n = reader.read(buffer)) != -1) {
							writer.write(buffer, 0, n);
						}
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						is.close();
					}

					JSONObject json = new JSONObject(writer.toString());
					JSONArray sessions = json.getJSONArray("session");

					for (int k=0; k<sessions.length(); k++){
						JSONObject session = sessions.getJSONObject(k);
						Session s = new Session();

						s.setDate(session.getString("date"));
						s.setTitle(session.getString("title"));

						JSONArray talks = session.getJSONArray("list");
						for (int j = 0; j<talks.length(); j++){
							JSONObject talk = talks.getJSONObject(j);
							Talk t = new Talk(j);
							t.setTitle(talk.getString("title"));
							try {
								t.setColor(talk.getString("color"));
							}catch (Exception er){

							}
							t.setSpeaker(talk.getString("speaker"));
							if (talk.has("aula")) t.setAula(talk.getString("aula"));
							else t.setAula(session.getString("place"));
							if (talk.has("abstract")) t.setAbstra(talk.getString("abstract"));

							if (talk.has("start")){
								String [] split = talk.getString("start").split(",");
								Calendar beginTime = Calendar.getInstance();
								beginTime.set(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2]),
										Integer.parseInt(split[3]),Integer.parseInt(split[4]));
								t.setStart(beginTime);
								String [] splitE = talk.getString("end").split(",");
								Calendar endTime = Calendar.getInstance();
								endTime.set(Integer.parseInt(splitE[0]),Integer.parseInt(splitE[1]),Integer.parseInt(splitE[2]),
										Integer.parseInt(splitE[3]),Integer.parseInt(splitE[4]));
								t.setEnd(endTime);
							}
							t.setTime(talk.getString("time"));

							s.addTalk(t);
						}

						devfestToAdd.addSession(s);

					}
					
					//act.devfest.add(devfestToAdd);
					act.devfest.add(devfestToAdd);

				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				} catch (NoSuchFieldException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				} catch (NotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				}catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					res = e.getLocalizedMessage();
					error = true;
				}

			}
			return res;
		}

		protected void onPostExecute(String result){
			if (act != null){
				act.endLoadingJson(error,result);
				this.detach();
			}
		}

		void detach(){
			act = null;
		}

		void attach(MainActivity activity){
			this.act = activity;
		}
	}


	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu_base, menu);
		return true;
	}


	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		/*if (item.getItemId() == R.id.menu_stream) {
			Intent toStream = new Intent(this, StreamActivity.class);
			startActivity(toStream);
			return true;
		}else if (item.getItemId() == R.id.menu_gdg) {
			Intent toGdg = new Intent(this, GDGActivity.class);
			startActivity(toGdg);
			return true;
		}else */if (item.getItemId() == R.id.menu_about) {
			Intent toGdg = new Intent(this, AboutActivity.class);
			startActivity(toGdg);
			return true;
		} else {
			return super.onOptionsItemSelected(item);
		}

	}



	/**
	 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
	 * sections of the app.
	 */
	public class SectionsPagerAdapter extends FragmentPagerAdapter {

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int i) {
			return fragments.get(i);
		}

		@Override
		public int getCount() {
			return fragments.size();
		}

		@Override
		public CharSequence getPageTitle(int position) {
			if (position == 0){
				int resourceId=getResources().getIdentifier("title_fest"+fragment_selected, "string", getPackageName());
				return getResources().getString(resourceId);
			}
			else return "Sponsor & Partner"; 

		}
	}


	@Override
	public boolean onNavigationItemSelected(int itemPosition, long itemId) {
		if (fragment_selected == itemPosition) return false;
		else{

			loadDevfest(itemPosition);
			/*AllListFragment all = (AllListFragment) fragments.get(0);
			all.changeList(itemPosition);

			fragment_selected = itemPosition;*/
			

			return true;
		}
		// TODO Auto-generated method stub

	}

	public void showDetail(Talk talk) {
		app.selected = talk;
		// TODO Auto-generated method stub
		FragmentManager fm = getSupportFragmentManager();
		DetailFragment detailDialog = DetailFragment.newInstance();
		detailDialog.show(fm, "fragment_edit_name");

	}

}
